home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / asm_n_z.zip / SPY'.ASM < prev    next >
Assembly Source File  |  1987-05-11  |  17KB  |  430 lines

  1. name spyprime
  2.  
  3. rt        equ    0dh    ; return
  4. lf        equ    0ah    ; linefeed
  5. eof        equ    1ah    ; end of file
  6. ok_seg        equ    1    ; flag for segment decode check
  7. ok_off        equ    2    ; flag for offset decode check
  8. max_size    equ    4095    ; maximum size for SPY' search region
  9. beep_delay    equ    4    ; number of clock ticks between beeps
  10. timer_count    equ    597    ; frequency of beep = 1,193,180 / timer_count
  11.  
  12. ; These constants are used by the newint16h routine in this, the SPY' program.
  13. ; They are not needed for the SPY program.
  14. ckey1        equ    20cdh    ; value of first key (a "backwords" int 20)
  15. ckey2        equ    1234h    ; value of second key
  16. ckey3        equ    5678h    ; value of third key
  17.  
  18. code        segment
  19.         assume cs:code, ds:code
  20.  
  21.         org    0
  22. key1        dw    ?    ; offset of int 20h instruction
  23.                 ;   used to verify a PSP location
  24.  
  25.         org    100h
  26.  
  27. begin:        jmp    start    ; jump to program start location
  28.  
  29. ;-------------------------------------------------------------------------------
  30. ; This copyright message appears when SPY'.COM is "typed" to the screen.
  31. ;-------------------------------------------------------------------------------
  32.  
  33.         db    8,8,8,'   '
  34. copyright    db    rt,lf
  35.         db    "SPY' Copyright (C) 1987 by Charles Lazo III, v1.0"
  36.         db    eof,8,' ',rt,lf,'$'
  37.  
  38. key2        dw    ckey2    ; keys used to determine prior load of SPY'
  39. key3        dw    ckey3
  40.  
  41. oldint8             dd    ?    ; double word storage for old int 8 vector
  42. oldint16h    dd    ?    ; double word storage for old int 16 vector
  43. beeps        dw    0    ; number of beeps (notices) to send to user
  44. delay        dw    1    ; number of clock ticks 'til next beep
  45. beep_on        db    0    ; beep on/off status
  46. spy_size    dw    ?    ; number of bytes to spy on
  47. resident    db    0    ; indicates prior load of SPY' (0 = none)
  48.  
  49. spy_location    label    dword
  50. spy_off        dw    ?    ; storage for value of offset for SPYing
  51. spy_seg        dw    ?    ; storage for value of segment for SPYing
  52.  
  53. ;-------------------------------------------------------------------------------
  54. ; Comparisons of the spied region and the spy buffer (set up initially as a copy
  55. ; of the spied region) are made in this addition to the clock interrupt.
  56. ; Changes to the spied region are counted and the spy buffer is updated.  The
  57. ; speaker is turned on and off here, but frequency is set during program
  58. ; initialization.
  59. ;-------------------------------------------------------------------------------
  60.  
  61. newint8        proc    near
  62.         push    ax        ; save interrupted program's registers
  63.         push    bx
  64.         push    cx
  65.         push    si
  66.         push    di
  67.         push    ds
  68.         push    es
  69.  
  70.         mov    ax,cs        ; our data lies here
  71.         mov    ds,ax
  72.  
  73.         lea    si,spy_buffer    ; point to our buffer
  74.         les    di,spy_location    ; point to spied region
  75.         mov    cx,spy_size    ; compare whole region
  76.         cld            ; forward!
  77. cmp_more:    repz    cmpsb        ; compare until no match or cx = 0
  78.         jz    cmp_done    ; if zero, then cx = 0 and we're done
  79.         inc    beeps        ; account for a change
  80.         mov    al,es:[di-1]    ; change accounted; update spy_buffer
  81.         mov    [si-1],al
  82.         or    cx,cx        ; set zero flag by cx (avoid inf loop)
  83.         jmp    short cmp_more    ; continue 'til done
  84.  
  85. cmp_done:    cmp    beep_on,0    ; is the beep on?
  86.         jz    do_beep?    ; no, shall we do a beep?
  87.         dec    beep_on        ; yes, turn it off
  88.         in    al,97        ; get speaker control bits
  89.         and    al,0fch        ; set them off
  90.         out    97,al        ; turn off speaker
  91.         jmp    short exit    ; job done; get out
  92. do_beep?:    cmp    beeps,0        ; are there beeps to be done?
  93.         jz    delay1        ; no, get out
  94.         dec    delay        ; reduce delay 'til next beep
  95.         jnz    exit        ; not zero, then exit
  96.         in    al,97        ; get speaker control bits
  97.         or    al,3        ; set them on
  98.         out    97,al        ; turn on speaker
  99.         inc    beep_on        ; signal beep is on
  100.         mov    delay,beep_delay; reinitialize delay counter
  101.         dec    beeps        ; one less beep to do
  102.         jmp    short exit    ; leave now
  103. delay1:        mov    delay,1        ; don't wait for first beep of a series
  104. exit:        pop    es        ; restore registers
  105.         pop    ds
  106.         pop    di
  107.         pop    si
  108.         pop    cx
  109.         pop    bx
  110.         pop    ax
  111.         jmp    dword ptr cs:oldint8    ; continue with interrupt
  112. newint8        endp
  113.  
  114. ;-------------------------------------------------------------------------------
  115. ; Keyboard interrupt, int 16h, is issued with function number ah = 77h in the
  116. ; set_es routine.  If there has been no prior load of SPY', then the interrupt
  117. ; returns without changing anything.  However, if SPY' has been run previously,
  118. ; then this routine has been chained into the interrupt 16h handler and the
  119. ; issue of "keyboard" function number 77h causes the returned value of es to be
  120. ; what cs was for the original load of SPY'.
  121. ;-------------------------------------------------------------------------------
  122.  
  123. newint16h    proc    near
  124.         cmp    ah,77h        ; our cue?
  125.         jne    not_us        ; nah, not us
  126.         push    ax        ; save this
  127.         mov    ax,ckey1    ; have we a match for the first key?
  128.         cmp    ax,cs:key1
  129.         je    test_2nd    ; yes, test the 2nd key
  130.         jmp    short onward    ; no previous load found
  131. test_2nd:    mov    ax,ckey2    ; have we a match for the second key?
  132.         cmp    ax,cs:key2
  133.         je    test_3rd    ; yes, test the 3rd key
  134.         jmp    short onward    ; no previous load found
  135. test_3rd:    mov    ax,ckey3    ; have we a match for the third key?
  136.         cmp    ax,cs:key3
  137.         jne    onward        ; no match => no previous load
  138.         pop    ax        ; unstack saved value
  139.         mov    ax,cs        ; pass this cs in es
  140.         mov    es,ax
  141.         mov    ax,ckey1    ; pass these to inform set_es
  142.         mov    bx,ckey2
  143.         iret
  144. onward:        pop    ax        ; recover this
  145. not_us:        jmp    dword ptr cs:oldint16h    ; continue with interrupt
  146. newint16h    endp
  147.  
  148. ;-------------------------------------------------------------------------------
  149. ; Here the region spied upon is copied to an area of the TSR that remains in
  150. ; memory after termination, the spy_buffer.  The es register is equal either to
  151. ; cs if SPY' has not yet been loaded or to the value of cs when SPY' was loaded
  152. ; previously (accomplished by a call to the set_es routine).
  153. ;-------------------------------------------------------------------------------
  154.  
  155. copy_spied:    lea    di,spy_buffer    ; destination of copy
  156.         mov    si,spy_off    ; the offset is source of copy
  157.         mov    cx,spy_size    ; number of bytes to copy
  158.         mov    ax,spy_seg    ; load segment of SPY' region to ds
  159.         push    ds        ; SOD (save our data)
  160.         mov    ds,ax
  161.         cld            ; forward copy
  162.         rep    movsb        ; copy the SPY' region to spy_buffer
  163.         pop    ds        ; RestoreOD
  164.  
  165.         cmp    resident,0    ; is SPY' currently resident in memory?
  166.         je    tsr        ; no, make it so
  167.         mov    ax,4c00h    ; yes, end with error code 0
  168.         int    21h
  169.  
  170. ;-------------------------------------------------------------------------------
  171. ; SPY' has not yet been loaded into memory, so we do it now.  First the 8253-5
  172. ; chip that generates the frequency of the beeps is initialized with the value
  173. ; given by the constant timer_count.  Then the new interrupt 8 routine is
  174. ; spliced in and finally the constant max_size is used to reserve enough memory
  175. ; for the largest permissible spy buffer.
  176. ;-------------------------------------------------------------------------------
  177.  
  178. tsr:        mov    delay,beep_delay; initialize delay counter
  179.  
  180.         ; set 8253-5 programmable timer to chosen frequency
  181.         mov    al,182        ; byte to initialize 8253 timer
  182.         out    67,al        ; tell timer next two bytes are count
  183.         mov    ax,timer_count    ; get timer count
  184.         out    66,al        ; output low byte
  185.         mov    al,ah
  186.         out    66,al        ; output high byte
  187.  
  188.         mov    ax,3508h    ; get the interrupt 8 (clock) vector
  189.         int    21h        ;   with DOS function 35h call
  190.  
  191. ; Retain offset and segment of interrupt 8 vector:
  192.  
  193.         mov    word ptr cs:oldint8,bx
  194.         mov    word ptr cs:oldint8+2,es
  195.  
  196.         lea    dx,newint8    ; place offset in dx
  197.         mov    ax,2508h    ; set its pointer into interrupt table
  198.         int    21h        ;   with DOS function 25h call
  199.  
  200.         mov    ax,3516h    ; get the int 16h (keyboard) vector
  201.         int    21h        ;   with DOS function 35h call
  202.  
  203. ; Retain offset and segment of interrupt 16h vector:
  204.  
  205.         mov    word ptr cs:oldint16h,bx
  206.         mov    word ptr cs:oldint16h+2,es
  207.  
  208.         lea    dx,newint16h    ; place offset in dx
  209.         mov    ax,2516h    ; set its pointer into interrupt table
  210.         int    21h        ;   with DOS function 25h call
  211.  
  212.         lea    dx,spy_buffer    ; where SPY' buffer begins
  213.         mov    cx,max_size    ; add the maximum size of the buffer:
  214.         add    dx,cx
  215.         mov    cl,4        ; compute number of paragraphs to save:
  216.         shr    dx,cl        ;   bytes to paragraphs in dx
  217.         inc    dx        ;   insure sufficient size for buffer
  218.         mov    ax,3100h    ; terminate but stay resident code = 0
  219.         int    21h
  220.  
  221. ;---------------------------------------------------------